class Sheet18 {

}

object Sheet18 extends App {
  val a = new Pair1(5, 2)
  println(a.smaller)

  val b = new Pair2(2, 3)
  println(b.smaller)

  val c = new Pair3(Teacher("a"), Teacher("b"))
  println(c.replaceFirst(Person("c")))
}

class Pair1[T](val first: T, val second: T)(implicit ev: T => Comparable[T]) {
  def smaller: T = if (first.compareTo(second) < 0) first else second // Error
}

class Pair2[T: Ordering](val first: T, val second: T) {
  def smaller(implicit ord: Ordering[T]): T = if (ord.compare(first, second) < 0) first else second
}

class Pair3[T](val first: T, val second: T) {
  def replaceFirst[R >: T](newFirst: R) = new Pair3[R](newFirst, second)
}

class Person(val name: String)

object Person {
  def apply(name: String): Person = new Person(name)
}

class Teacher(name: String) extends Person(name)

object Teacher {
  def apply(name: String): Teacher = new Teacher(name)
}